package com.wnxy.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wnxy.admin.dto.*;
import com.wnxy.admin.entity.*;
import com.wnxy.admin.mapper.*;
import com.wnxy.admin.service.IChargingReportService;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Year;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChargingReportServiceImpl implements IChargingReportService {

    private final OrderMapper orderMapper;
    private final RechargeMapper rechargeMapper;
    private final ChargingPileMapper chargingPileMapper;
    private final ChargingCardMapper chargingCardMapper;
    private final CustomerMapper customerMapper;
    private final ChargingStationMapper chargingStationMapper;

    public ChargingReportServiceImpl(OrderMapper orderMapper, RechargeMapper rechargeMapper, ChargingPileMapper chargingPileMapper, ChargingCardMapper chargingCardMapper, CustomerMapper customerMapper, ChargingStationMapper chargingStationMapper) {
        this.orderMapper = orderMapper;
        this.rechargeMapper = rechargeMapper;
        this.chargingPileMapper = chargingPileMapper;
        this.chargingCardMapper = chargingCardMapper;
        this.customerMapper = customerMapper;
        this.chargingStationMapper = chargingStationMapper;
    }

    /** 运营分析
     * @author nhj
     *  导出运营分析数据
     */
    @Override
    public List<OperatorReportDto> getOperatorExport() {
        List<OperatorReportDto> operatorReportDtos = orderMapper.selectOperatorExport();
        return operatorReportDtos;
    }

    /** 运营分析
     * @author nhj
     *
     */
    @Override
    public PageInfo<OperatorReportDto> getOperatorReport(Integer pageNum, Integer pageSize,Long chargingStationId,String createTime) {

        PageHelper.startPage(pageNum,pageSize);

        List<OperatorReportDto> operatorReportDtos = orderMapper.selectOperatorReport(chargingStationId,createTime);

        return new PageInfo<>(operatorReportDtos);
    }



    /**
     * @author nhj
     *  导出客户分析数据
     */
    @Override
    public List<CustomerReportDto> getCustomerExport(Long chargingStationId, String createTime) {

        List<Customer> customers = customerMapper.selectList(Wrappers.lambdaQuery(Customer.class));

        List<CustomerReportDto> customerReportDtos = orderMapper.selectCustomerReport( null, null);
        customerReportDtos.forEach(c->{
            ChargingStation chargingStation = chargingStationMapper.selectOne(Wrappers.lambdaQuery(ChargingStation.class)
                    .eq(ChargingStation::getChargingStationName, c.getChargingStation()));
            if (chargingStation!=null){
                c.setAddress(chargingStation.getChargingStationPlace());
            }
            if (customers.size()!=0){
                c.setCustomerTotal(customers.size());
            }

        });
        return customerReportDtos;
    }

    /** 客户分析
     * @author nhj
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<CustomerReportDto> customerReport(Integer pageNum, Integer pageSize,Long chargingStationId,String createTime) {

        List<Customer> customers = customerMapper.selectList(Wrappers.lambdaQuery(Customer.class));

        List<CustomerReportDto> customerReportDtos = orderMapper.selectCustomerReport( chargingStationId, createTime);
          customerReportDtos.forEach(c->{
              ChargingStation chargingStation = chargingStationMapper.selectOne(Wrappers.lambdaQuery(ChargingStation.class)
                      .eq(ChargingStation::getChargingStationName, c.getChargingStation()));
             if (chargingStation!=null){
                 c.setAddress(chargingStation.getChargingStationPlace());
             }
              if (customers.size()!=0){
                  c.setCustomerTotal(customers.size());
              }

          });

        // 手动分页
        int totalSize = customerReportDtos.size();
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, totalSize);

        // 截取相应范围的数据
        customerReportDtos = customerReportDtos.subList(startIndex, endIndex);

        return new  PageResult((long)totalSize,customerReportDtos);
    }




    /**
     * 财务报表
     * @author nhj
     * @param pageNum
     * @param pageSize
     * @param customerName
     * @return
     */
    @Override
    public PageResult<FinanceReportDto> financeReport(Integer pageNum, Integer pageSize,String customerName) {

        // 消费记录
        List<ConsumeDto> consumeDtos = orderMapper.selectConsumeAll(customerName);
        // 充值记录
        List<TopUpDto> topUpDtos = rechargeMapper.selectFinanceAll(customerName);

        // 使用Map以客户名称+日期为键，存储财务报告
        Map<String, FinanceReportDto> reportMap = new HashMap<>();
        consumeDtos = consumeDtos.stream().filter(c -> c.getExpenditureDate() != null).collect(Collectors.toList());

        // 处理消费记录
        for (ConsumeDto consumeDto : consumeDtos) {
            String key = getKey(consumeDto.getCustomerName(), consumeDto.getExpenditureDate());
            FinanceReportDto reportDto = reportMap.getOrDefault(key, new FinanceReportDto());
            reportDto.setCustomerName(consumeDto.getCustomerName());
            reportDto.setCardId(consumeDto.getCardId());
            reportDto.setTotalExpenditure(reportDto.getTotalExpenditure().add(consumeDto.getExpenditure()));
            reportDto.setDate(consumeDto.getExpenditureDate());
            reportMap.put(key, reportDto);
        }

        // 处理充值记录
        for (TopUpDto topUpDto : topUpDtos) {
            String key = getKey(topUpDto.getCustomerName(), topUpDto.getRechargeAmountDate());
            FinanceReportDto reportDto = reportMap.getOrDefault(key, new FinanceReportDto());
            reportDto.setCustomerName(topUpDto.getCustomerName());
            reportDto.setCardId(topUpDto.getCardId());
            reportDto.setTotalRecharge(reportDto.getTotalRecharge().add(topUpDto.getRechargeAmount()));
            reportDto.setDate(topUpDto.getRechargeAmountDate());
            reportMap.put(key, reportDto);
        }

        // 转换Map中的值为List
        List<FinanceReportDto> dtos = new ArrayList<>(reportMap.values());
        Collections.sort(dtos, Comparator.comparing(FinanceReportDto::getDate));

        // 手动分页
        int totalSize = dtos.size();
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, totalSize);

        // 截取相应范围的数据
        dtos = dtos.subList(startIndex, endIndex);

        dtos.forEach( d ->{
            ChargingCard chargingCard = chargingCardMapper.selectOne(Wrappers.lambdaQuery(ChargingCard.class)
                    .eq(ChargingCard::getChargingCardNumber, d.getCardId()));
            d.setBalance(chargingCard.getChargingCardMoney());
        });


        return  new  PageResult((long) totalSize,dtos);
    }

    /**
     * 导出财务信息
     *
     * @return
     */
    @Override
    public List<FinanceReportDto> getFinanceExport() {
        // 消费记录
        List<ConsumeDto> consumeDtos = orderMapper.selectConsumeAll(null);
        // 充值记录
        List<TopUpDto> topUpDtos = rechargeMapper.selectFinanceAll(null);

        // 使用Map以客户名称+日期为键，存储财务报告
        Map<String, FinanceReportDto> reportMap = new HashMap<>();
        consumeDtos = consumeDtos.stream().filter(c -> c.getExpenditureDate() != null).collect(Collectors.toList());

        // 处理消费记录
        for (ConsumeDto consumeDto : consumeDtos) {
            String key = getKey(consumeDto.getCustomerName(), consumeDto.getExpenditureDate());
            FinanceReportDto reportDto = reportMap.getOrDefault(key, new FinanceReportDto());
            reportDto.setCustomerName(consumeDto.getCustomerName());
            reportDto.setCardId(consumeDto.getCardId());
            reportDto.setTotalExpenditure(reportDto.getTotalExpenditure().add(consumeDto.getExpenditure()));
            reportDto.setDate(consumeDto.getExpenditureDate());
            reportMap.put(key, reportDto);
        }

        // 处理充值记录
        for (TopUpDto topUpDto : topUpDtos) {
            String key = getKey(topUpDto.getCustomerName(), topUpDto.getRechargeAmountDate());
            FinanceReportDto reportDto = reportMap.getOrDefault(key, new FinanceReportDto());
            reportDto.setCustomerName(topUpDto.getCustomerName());
            reportDto.setCardId(topUpDto.getCardId());
            reportDto.setTotalRecharge(reportDto.getTotalRecharge().add(topUpDto.getRechargeAmount()));
            reportDto.setDate(topUpDto.getRechargeAmountDate());
            reportMap.put(key, reportDto);
        }

        // 转换Map中的值为List
        List<FinanceReportDto> dtos = new ArrayList<>(reportMap.values());

        Collections.sort(dtos, Comparator.comparing(FinanceReportDto::getDate));

        dtos.forEach( d ->{
            ChargingCard chargingCard = chargingCardMapper.selectOne(Wrappers.lambdaQuery(ChargingCard.class)
                    .eq(ChargingCard::getChargingCardNumber, d.getCardId()));
            d.setBalance(chargingCard.getChargingCardMoney());
        });

        return dtos;
    }


    private String getKey(String customerName, Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return customerName + "-" + dateFormat.format(date);
    }



    /**
     * 能耗报表
     * @author nhj
     * @param pageNum
     * @param pageSize
     * @param id
     * @param endTime
     * @return
     */
    @Override
    public PageResult<ChargingPileReportDto> nengHaoReport(Integer pageNum, Integer pageSize, Long id, String endTime) {

        LambdaQueryWrapper<Order> queryWrapper = Wrappers.lambdaQuery(Order.class);

        if (id != null) {
            queryWrapper.eq(Order::getChargingStationId, id);
        }
        if (endTime != null) {
            queryWrapper.likeRight(Order::getEndTime,endTime);
        }
        if (endTime == null){
            Year year = Year.now();
            endTime= String.valueOf(year);
            queryWrapper.likeRight(Order::getEndTime,endTime);
        }

        List<Order> orders = orderMapper.selectList(queryWrapper);

        // 使用 Stream 进行分组
        Map<String, List<Order>> groupedOrders = orders.stream()
                .filter(o -> o.getEndTime() !=null)
                .collect(Collectors.groupingBy(Order::getChargingPileNumber));

        List<ChargingPileReportDto> resultList = new ArrayList<>();


        for (List<Order> stationOrders : groupedOrders.values()) {

            ChargingPileReportDto dto = new ChargingPileReportDto();

            //充电站编码
            String chargingPileNumber = stationOrders.get(0).getChargingPileNumber();
            //充电站名称
            ChargingPile chargingPile = chargingPileMapper.selectOne(Wrappers.lambdaQuery(ChargingPile.class)
                    .eq(ChargingPile::getChargingPileNumber, chargingPileNumber));

            BeanUtil.copyProperties(stationOrders.get(0), dto);

            if (chargingPile != null) {
                dto.setChargingPileName(chargingPile.getChargingPileName());
            }
            // 遍历订单列表，更新 DTO 的充电量和月报表
            for (Order order : stationOrders) {

                dto.setChargeAmount(order.getChargeAmount());
                dto.setEndTime(order.getEndTime());
                dto.updateMonthReport();
            }

            resultList.add(dto);
        }

        // 手动分页
        int totalSize = resultList.size();
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, totalSize);

        // 截取相应范围的数据
        resultList = resultList.subList(startIndex, endIndex);


        return new PageResult<>((long)totalSize,resultList);

    }


}
